package com.pf.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.Set;

/**
 * @author PanFei
 * @version 1.0.0
 * @createTime 2021/9/8
 */
@Slf4j
@Component
public class RestClient {

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 执行POST请求（默认 Content-type = application/json）
     *
     * @param url
     * @param reqParams
     * @param reqBody
     * @param reqHeaders
     * @param resultClass
     * @param <T>
     * @return
     */
    public <T> T executePostJson(String url, Map<String, String> reqParams, Object reqBody, Map<String, String> reqHeaders, Class<T> resultClass) {
        Assert.hasText(url, "请求参数【url】不能为空！");
        Assert.notNull(resultClass, "请求参数【resultClass】不能为空！");
        Assert.notNull(resultClass, "请求参数【reqHeaders】不能为空！");
        // 处理url后拼接的请求参数
        url = buildReqParamsStr(url, reqParams);
        // 处理请求头和请求体参数信息
        String contentType = reqHeaders.get(HttpHeaders.CONTENT_TYPE);
        if (!MediaType.APPLICATION_JSON_VALUE.equals(contentType)) {
            throw new RuntimeException("请求头contentType值不正确！值必须为【application/json】");
        }
        HttpEntity httpEntity = this.buildReqJsonBodyAndHeaders(reqBody, reqHeaders);
        try {
            ResponseEntity<T> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, resultClass);
            if (responseEntity != null && HttpStatus.OK.equals(responseEntity.getStatusCode())) {
                return responseEntity.getBody();
            }
        } catch (Exception e) {
            log.error(">>>>> RestClient - executePostJson error!", e);
        }
        return null;
    }


    /**
     * 组装请求url后面拼接的参数reqParams
     * <p>
     * 返回的结果为：
     * 如：http://localhost:8080/list?requestId=1111&accessToken=2222
     *
     * @param url
     * @param reqParams
     * @return
     */
    private String buildReqParamsStr(String url, Map<String, String> reqParams) {
        String reqParamsStr = "";
        if (reqParams != null && reqParams.size() > 0) {
            Set<String> keys = reqParams.keySet();
            for (String key : keys) {
                reqParamsStr = reqParamsStr + key + "=" + reqParams.get(key) + "&";
            }
            reqParamsStr = reqParamsStr.substring(0, reqParamsStr.length() - 1);
        }
        if (StringUtils.isNotBlank(reqParamsStr)) {
            url = url + "?" + reqParamsStr;
        }
        return url;
    }

    /**
     * 设置请求体参数（json请求体）和请求头信息，并返回HttpEntity对象
     *
     * @param reqBodyParams
     * @param reqHeaders
     * @return
     */
    private HttpEntity buildReqJsonBodyAndHeaders(Object reqBodyParams, Map<String, String> reqHeaders) {
        // 请求头
        HttpHeaders headers = null;
        if (reqHeaders != null && reqHeaders.size() > 0) {
            headers = new HttpHeaders();
            Set<String> headerKeys = reqHeaders.keySet();
            for (String headerKey : headerKeys) {
                headers.add(headerKey, reqHeaders.get(headerKey));
            }
        }
        String reqBodyParamsStr = null;
        if (reqBodyParams != null) {
            reqBodyParamsStr = reqBodyParams instanceof String ? (String) reqBodyParams : JacksonUtils.toJsonString(reqBodyParams);
        }
        return new HttpEntity<>(reqBodyParamsStr, headers);
    }
}
